from rest_framework.viewsets import ViewSet
from rest_framework.response import Response
from rest_framework.decorators import action
from rest_framework.permissions import AllowAny
from django.db import connections
from drf_yasg.utils import swagger_auto_schema
from utils.db_utils import DynamicDBManager


class DatabaseTestViewSet(ViewSet):
    """
    数据库连接测试视图集
    支持固定数据库测试和动态指定数据库测试
    """
    permission_classes = [AllowAny]  # 允许匿名访问所有测试接口

    # 通用测试方法（内部复用）
    def _test_db_connection(self, db_alias):
        """测试指定别名的数据库连接"""
        try:
            # 检查数据库别名是否存在，不存在则尝试加载配置
            if db_alias not in connections:
                DynamicDBManager.load_third_party_dbs()  # 加载第三方数据库配置

            # 再次检查是否存在
            if db_alias not in connections:
                return Response(
                    {"message": f"数据库别名 '{db_alias}' 不存在，请检查配置"},
                    status=404
                )

            # 尝试连接并执行测试查询
            with connections[db_alias].cursor() as cursor:
                cursor.execute("SELECT 1")
                cursor.fetchone()  # 执行查询并获取结果

            return Response(
                {"message": f"数据库 '{db_alias}' 连接成功"},
                status=200
            )

        except Exception as e:
            return Response(
                {"message": f"数据库 '{db_alias}' 连接失败：{str(e)}"},
                status=500
            )

    # 1. 固定数据库测试接口（与原风格保持一致）
    @swagger_auto_schema(
        operation_summary="测试 default 数据库",
        operation_description="验证与 default 数据库的连接状态",
        responses={200: "连接成功", 404: "数据库不存在", 500: "连接失败"}
    )
    @action(detail=False, methods=['get'], url_path='default')
    def test_default(self, request):
        return self._test_db_connection('default')

    @swagger_auto_schema(
        operation_summary="测试 log_db 数据库",
        operation_description="验证与 log_db 数据库的连接状态",
        responses={200: "连接成功", 404: "数据库不存在", 500: "连接失败"}
    )
    @action(detail=False, methods=['get'], url_path='log_db')
    def test_log_db(self, request):
        return self._test_db_connection('log_db')

    # 2. 动态指定数据库测试接口（新增功能）
    from drf_yasg import openapi
    from drf_yasg.utils import swagger_auto_schema

    # ... 其他代码不变 ...

    @swagger_auto_schema(
        operation_summary="动态测试指定数据库",
        operation_description="通过参数 db_alias 动态指定要测试的数据库",
        # 定义请求参数
        manual_parameters=[
            openapi.Parameter(
                name="db_alias",  # 参数名（与代码中一致）
                in_=openapi.IN_QUERY,  # 参数位置：URL查询参数（?db_alias=xxx）
                description="要测试的数据库别名（如 user_center、order_db）",  # 参数描述
                type=openapi.TYPE_STRING,  # 参数类型：字符串
                required=True,  # 是否必填
                example="user_center"  # 示例值
            )
        ],
        responses={
            200: "连接成功",
            400: "缺少 db_alias 参数",
            404: "数据库别名不存在",
            500: "连接失败（含错误详情）"
        }
    )
    @action(detail=False, methods=['get'], url_path='dynamic')
    def test_dynamic(self, request):
        """通过请求参数 db_alias 动态指定要测试的数据库"""
        db_alias = request.query_params.get('db_alias')
        if not db_alias:
            return Response(
                {"message": "请通过参数 ?db_alias=xxx 指定数据库别名"},
                status=400
            )

        # 在测试连接前获取并打印连接信息
        connection_info = None
        try:
            # 1. 先尝试加载最新配置（确保获取到最新的连接信息）
            DynamicDBManager.load_third_party_dbs()

            # 2. 检查数据库是否已在连接配置中
            if db_alias in connections.databases:
                # 获取完整连接配置（隐藏密码，避免敏感信息泄露）
                connection_config = connections.databases[db_alias].copy()
                if 'PASSWORD' in connection_config:
                    connection_config['PASSWORD'] = '******'  # 密码脱敏
                connection_info = connection_config
                print(f"===== 数据库 {db_alias} 连接信息 =====")
                print(connection_info)  # 控制台打印
            else:
                connection_info = f"数据库别名 {db_alias} 未在连接配置中找到"
                print(connection_info)
        except Exception as e:
            connection_info = f"获取连接信息失败：{str(e)}"
            print(connection_info)

        # 3. 调用测试连接方法
        response = self._test_db_connection(db_alias)

        # 4. 可选：将连接信息添加到响应中（方便前端调试）
        if hasattr(response, 'data'):
            response.data['connection_info'] = connection_info

        return response
